package com.next

import grails.converters.JSON
import grails.transaction.Transactional
import org.springframework.security.access.annotation.Secured

import java.text.SimpleDateFormat

import static org.springframework.http.HttpStatus.*

@Secured(['ROLE_ADMINISTRATOR', 'ROLE_COMPANY_ADMINISTRATOR', 'ROLE_COMPANY_USER'])
@Transactional(readOnly = true)
class OpportunityController
{

    //    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
    OpportunityService opportunityService

    def springSecurityService
    def exportService

    def visualization()
    {
        def username = springSecurityService?.getPrincipal()?.username
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd")
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM")
        Calendar now = Calendar.getInstance()
        now.set(Calendar.DAY_OF_MONTH, 1)

        String beginDate = sdf.format(now.getTime())
        String date = sdf2.format(now.getTime())

        def opportunityList = Opportunity.findAll("from Opportunity where createdDate >= '${beginDate}' and user.username = '${username}'")
        def opportunityList2 = Opportunity.findAll("from Opportunity where createdDate >= '${beginDate}' and user.username = '${username}' and lead is not null")
        def leadList = Lead.findAll("from Lead where createdDate >= '${beginDate}' and user.username = '${username}'")
        Calendar startTime = Calendar.getInstance()
        def amount1st = 0.0
        def amount2nd = 0.0
        def amount3rd = 0.0
        def amount4th = 0.0
        def amount5th = 0.0
        def amountCurrentWeek = 0.0
        def countCurrentWeek = 0
        def amountCurrentMonth1 = 0.0
        def countCurrentMonth1 = 0
        def amountCurrentMonth2 = 0.0
        def countCurrentMonth2 = 0
        opportunityList.each {
            if (it.stage?.name == '已入围')
            {
                amount1st += it.amount
            }
            if (it.stage?.name == '需求分析')
            {
                amount2nd += it.amount
            }
            if (it.stage?.name == '解决方案')
            {
                amount3rd += it.amount
            }
            if (it.stage?.name == '谈判')
            {
                amount4th += it.amount
            }
            if (it.stage?.name == '接近成功')
            {
                amount5th += it.amount
            }
            startTime.setTime(it.startTime)
            if (now.get(Calendar.WEEK_OF_YEAR) == startTime.get(Calendar.WEEK_OF_YEAR))
            {
                amountCurrentWeek += it.amount
                countCurrentWeek++
            }
        }
        opportunityList2.each {
            amountCurrentMonth1 += it.amount
            countCurrentMonth1++
        }
        leadList.each {
            //amountCurrentMonth2 += it .amount
            countCurrentMonth2++
        }
        def countConversionRate = 0.0
        def amountConversionRate = 0.0
        if (amountCurrentMonth2 > 0)
        {
            countConversionRate = countCurrentMonth1 / countCurrentMonth2
            amountConversionRate = amountCurrentMonth1 / amountCurrentMonth2
        }
        def name = ["已入围", "需求分析", "解决方案", "谈判", "已经成功"]
        def value = []
        value.add(amount1st)
        value.add(amount2nd)
        value.add(amount3rd)
        value.add(amount4th)
        value.add(amount5th)

        render([name: name, value: value, amountCurrentWeek: amountCurrentWeek, countCurrentWeek: countCurrentWeek, countConversionRate: countConversionRate, amountConversionRate: amountConversionRate, date: date] as JSON)
    }

    def opportunityList(Integer max)
    {
        def username = springSecurityService?.getPrincipal()?.username
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd")
        Calendar currentMonth = Calendar.getInstance()
        currentMonth.set(Calendar.DAY_OF_MONTH, 1)
        String cMonth = sdf.format(currentMonth.getTime())

        def stage = params['stage']
        def status = params['status']
        def opportunityList = Opportunity.findAll("from Opportunity where createdDate >= '${cMonth}' and user.username = '${username}' and stage.name = '${stage}' and status.name = '${status}'", [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = Opportunity.executeQuery("select count(id) from Opportunity where createdDate >= '${cMonth}' and user.username = '${username}' and stage.name = '${stage}' and status.name = '${status}'")
        respond opportunityList, model: [opportunityCount: count[0]]
    }

    def index(Integer max)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def opportunityList = Opportunity.findAll("from Opportunity where user.username = '${username}' order by modifiedDate desc", [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = Opportunity.executeQuery("select count(id) from Opportunity where user.username = '${username}'")

        respond opportunityList, model: [opportunityCount: count[0]]
    }

    def show(Opportunity opportunity)
    {
        def attachmentList = Attachment.findAll("from Attachment where opportunity.id = ?", [opportunity.id])
        def noteList = Note.findAll("from Note where opportunity.id = ?", [opportunity.id])
        def appointmentList = Activity.findAll("from Activity where opportunity.id = ? and type.id = ?", [opportunity.id, ActivityType.find("from ActivityType where name = 'Appointment'")?.id])
        def taskList = Activity.findAll("from Activity where opportunity.id = ? and type.id = ?", [opportunity.id, ActivityType.find("from ActivityType where name = 'Task'")?.id])
        def teamList = OpportunityTeam.findAll("from OpportunityTeam where opportunity.id = ?", [opportunity.id])
        def flexFieldInstanceList = FlexFieldInstance.findAll("from FlexFieldInstance where opportunity.id = ? order by modifiedDate desc", [opportunity.id])
        def workflowInstanceList = WorkflowInstance.findAll("from WorkflowInstance where opportunity.id = ?", [opportunity.id])
        def opportunityHistoryList = OpportunityHistory.findAll("from OpportunityHistory where parent.id = ? order by createdDate desc", [opportunity.id])
        respond opportunity, model: [attachmentList: attachmentList, noteList: noteList, appointmentList: appointmentList, taskList: taskList, teamList: teamList, flexFieldInstanceList: flexFieldInstanceList, workflowInstanceList: workflowInstanceList, teamName: 'opportunityTeam', opportunityHistoryList: opportunityHistoryList]
    }

    def create()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        respond new Opportunity(params), model: [user: user]
    }

    @Transactional
    def save(Opportunity opportunity)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (opportunity == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (opportunity.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond opportunity.errors, model: [user: user], view: 'create'
            return
        }

        opportunity.save flush: true

        opportunityService.initOpportunity opportunity

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'opportunity.label', default: 'Opportunity'), opportunity.id])
                redirect opportunity
            }
            '*' { respond opportunity, [status: CREATED] }
        }
    }

    def edit(Opportunity opportunity)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        respond opportunity, model: [user: user]
    }

    @Transactional
    def update(Opportunity opportunity)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (opportunity == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (opportunity.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond opportunity.errors, model: [user: user], view: 'edit'
            return
        }

        opportunity.save flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'opportunity.label', default: 'Opportunity'), opportunity.id])
                redirect opportunity
            }
            '*' { respond opportunity, [status: OK] }
        }
    }

    @Transactional
    def delete(Opportunity opportunity)
    {

        if (opportunity == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        opportunity.delete flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'opportunity.label', default: 'Opportunity'), opportunity.id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NO_CONTENT }
        }
    }

    protected void notFound()
    {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'opportunity.label', default: 'Opportunity'), params.id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NOT_FOUND }
        }
    }

    def searchOpportunity()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def serialNumber = params["serialNumber"]
        String sql = "from Opportunity as u where 1=1 and u.user.username = '${username}'"
        if (serialNumber)
        {
            sql += " and u.serialNumber like '%${serialNumber}%'"
        }

        def accountName = params["accountName"]
        if (accountName)
        {
            sql += " and u.account.name like '%${accountName}%'"
        }

        def productName = params["productName"]
        if (productName)
        {
            sql += " and u.product.name like '%${productName}%'"
        }

        String countSql = "select count(u.id) " + sql
        sql += ' order by modifiedDate desc'

        def list = Opportunity.findAll(sql, [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = Opportunity.executeQuery(countSql)

        respond list, model: [opportunityCount: count[0], params: params], view: 'index'
    }

    def exportOpportunity()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def serialNumber = params["serialNumber"]
        String sql = "from Opportunity as u where 1=1 and u.user.username = '${username}'"
        if (serialNumber)
        {
            sql += " and u.serialNumber like '%${serialNumber}%'"
        }
        String countSql = "select count(u.id) " + sql
        sql += ' order by modifiedDate desc'

        def list = Opportunity.findAll(sql)
        def count = Opportunity.executeQuery(countSql)

        if (params?.f && params.f != "html")
        {
            response.contentType = grailsApplication.config.grails.mime.types[params.f]
            response.setHeader("Content-disposition", "attachment; filename=opportunity.${params.extension}")
            List fields = ["stage.name", "type.name", "probability", "amount", "account.name", "productLine.name", "product.name", "purchasingMethod.name", "startTime", "endTime", "source.name", "status.name", "causeOfFailure", "descriptionOfFailure", "createdDate", "modifiedDate"]
            Map labels = ["stage.name": "商机阶段", "type.name": "商机类型", "probability": "几率", "amount": "金额", "account.name": "客户", "productLine.name": "产品线", "product.name": "产品", "purchasingMethod.name": "采购方法", "startTime": "商机发现时间", "endTime": "客户预计采购时间", "source.name": "来源", "status.name": "状态", "causeOfFailure": "失败原因", "descriptionOfFailure": "商机描述", "createdDate": "创建时间", "modifiedDate": "修改时间"]
            exportService.export(params.f, response.outputStream, list, fields, labels, [:], [:])
        }
    }

    def getProducts()
    {
        def productList = []
        def productLine = ProductLine.findById(params['productLine'])
        if (productLine)
        {
            productList = Product.executeQuery("select id, name from Product where productLine.id = ${productLine?.id} and active = true")
        }

        render([status: "success", productList: productList] as JSON)
    }
}
